#pragma once
#include <cstdio>
#include <ctime>
#include <random>
#include <iostream>
#include <string>
#include <memory>
#include <iomanip>

#include <sstream>

#include <jsoncpp/json/json.h>
#include <thread>
#include <arpa/inet.h>

#include "Common.hpp"

// resp
namespace zj
{
    enum class MType
    {
        ADD_REQUEST,
        ADD_RESPONSE
    };

    enum class RCode
    { /*错误码*/
      RCODE_OK = 0,
      RCODE_PARSE_FAILED,
      RCODE_ERROR_MSGTYPE,
      RCODE_INVALID_MSG,
      RCODE_DISCONNECTED,
      RCODE_INVALID_PARAMS,
      RCODE_NOT_FOUND_SERVICE,
      RCODE_INVALID_OPTYPE,
      RCODE_NOT_FOUND_TOPIC,
      RCODE_INTERNAL_ERROR
    };

    const size_t lenFieldsLength = 4;
    const size_t mtypeFieldsLength = 4;
    const size_t idlenFieldsLength = 4;
    class BaseMessage
    {
    public:
        // using ptr = std::shared_ptr<BaseMessage>;
        virtual ~BaseMessage() {}
        virtual void setId(const std::string &id)
        {
            _rid = id;
        }
        virtual std::string rid() { return _rid; }
        virtual void setMType(MType mtype)
        {
            _mtype = mtype;
        }
        virtual MType mtype() { return _mtype; }
        virtual std::string serialize() = 0;
        virtual bool unserialize(const std::string &msg) = 0;
        virtual bool check() = 0;

    private:
        MType _mtype;
        std::string _rid;
    };

    class JsonMessage : public BaseMessage
    {
    public:
        // using ptr = std::shared_ptr<JsonMessage>;
        JsonMessage() {}

        std::string serialize() override
        {
            std::string body;
            JsonAPI::serialize(_body, &body);
            return body;
        }

        bool unserialize(const std::string &msg) override
        {
            bool ret = JsonAPI::delserialize(_body, msg);
            return ret;
        }

        ~JsonMessage() override {}

        Json::Value _body;
    };

    class JsonRequest : public JsonMessage
    {
    };

    class JsonResponse : public JsonMessage
    {
    public:
        virtual RCode rcode()
        {
            return (RCode)_body["RCODE"].asInt();
        }
        virtual void setRCode(RCode rcode)
        {
            _body["RCODE"] = (int)rcode;
        }

        bool check() override
        {
            if (_body["RCODE"].isIntegral() == false)
            {
                std::cout << "RCODE返回类型错误" << std::endl;
                return false;
            }
            if (_body["RCODE"].isNull() == true)
            {
                std::cout << "结果中没有RCODE" << std::endl;
                return false;
            }
            return true;
        }
    };

    // 请求中含有 x y std::string oper选项;
    class NetCalRequest : public JsonRequest
    {
    public:
        void setparms(Json::Value parms)
        {
            _body["PARMS"] = parms;
        }

        Json::Value parms() const
        { // 确保函数是const，因为我们不会修改成员变量
            return _body["PARMS"];
        }

        bool check() override
        {
            if (_body["PARMS"].isObject() == false || _body["PARMS"].isNull())
            {
                std::cout << "NETCAL请求中没有参数或者参数类型错误" << std::endl;
                return false;
            }
            return true;
        }
    };

    // 返回中含有 result rcode选项;
    class NetCalResponse : public JsonResponse
    {
    public:
        bool check() override
        {
            if (_body["RESULT"].isIntegral() == false)
            {
                std::cout << "RESULT返回类型错误" << std::endl;
                return false;
            }
            if (_body["RESULT"].isNull() == true)
            {
                std::cout << "服务器没有结果回复" << std::endl;
                return false;
            }
            return true;
        }

        void setresult(int result)
        {
            _body["RESULT"] = result;
        }
        int result()
        {
            return _body["RESULT"].asInt();
        }
    };

    /*enum class MType
    {
        ADD_REQUEST,
        ADD_RESPONSE
    };

    enum class RCode
    {
      RCODE_OK = 0,
      RCODE_PARSE_FAILED,
      RCODE_ERROR_MSGTYPE,
      RCODE_INVALID_MSG,
      RCODE_DISCONNECTED,
      RCODE_INVALID_PARAMS,
      RCODE_NOT_FOUND_SERVICE,
      RCODE_INVALID_OPTYPE,
      RCODE_NOT_FOUND_TOPIC,
      RCODE_INTERNAL_ERROR
    };*/

    class LVProtocol // LV模式
    {
    public:
        //  Len + VType + idlen + id + 序列化body
        static std::string Encode(std::shared_ptr<zj::BaseMessage> msg) // 这个就是发送前的添加报头 ,
        {
            std::string body = msg->serialize();
            std::cout << "body: " << body.c_str() << std::endl;
            std::string uid = msg->rid();
            auto mtype = htonl((int32_t)msg->mtype());
            uint32_t h_total_len = mtypeFieldsLength + idlenFieldsLength + uid.size() + body.size();
            uint32_t n_total_len = htonl(h_total_len);
            auto idlen = htonl(uid.size());
            std::cout << "h_total_len: " << h_total_len << std::endl;
            std::cout << "uid.size(): " << uid.size() << std::endl;

            std::string result;
            result.reserve(h_total_len);
            result.append((char *)&n_total_len, lenFieldsLength);
            result.append((char *)&mtype, mtypeFieldsLength);
            result.append((char *)&idlen, idlenFieldsLength);
            result.append(uid);
            result.append(body);

            std::cout << "result: " << result << std::endl;
            return result;
        }
        /////////////////////////////////////////////////////////////////////////////
        static bool Decode(std::string &mesg, std::shared_ptr<zj::BaseMessage> body) // 接收报文，满足条件就去除报头放入body中  ，并且对mesg截断
        {
            std::cout << "到这了Decode" << std::endl;
            
            // 检查body指针是否有效
            if (!body) {
                std::cout << "错误：传入的body指针为空!" << std::endl;
                return false;
            }
            
            std::cout << "mseg.size: " << mesg.size() << " bytes" << std::endl;
            
            // 二进制数据不能直接用c_str()打印，因为可能包含null字符
            if (mesg.size() > 0) {
                std::cout << "mseg数据前10字节(十六进制): ";
                for (size_t i = 0; i < std::min<size_t>(10, mesg.size()); ++i) {
                    std::cout << std::hex << std::setw(2) << std::setfill('0') 
                              << static_cast<int>(static_cast<unsigned char>(mesg[i])) << " ";
                }
                std::cout << std::dec << std::endl;
            }
            
            if (mesg.size() < sizeof(uint32_t))
            {
                std::cout << "到这了false1: 消息太短(" << mesg.size() << " bytes)，无法包含长度字段(" << sizeof(uint32_t) << " bytes)" << std::endl;
                return false; // 消息太短，无法包含长度字段
            }
            
            // 检查长度字段是否有效
            uint32_t total_len;
            memcpy(&total_len, mesg.data(), sizeof(total_len));
            uint32_t n_total_len = total_len; // 网络字节序的原始值
            total_len = ntohl(total_len); // 转换为主机字节序
            
            std::cout << "网络字节序长度: " << n_total_len << ", 主机字节序长度: " << total_len << std::endl;
            
            // 安全检查：防止过大的长度值
            if (total_len > 1024 * 1024) { // 限制最大1MB
                std::cout << "错误：长度值过大(" << total_len << "), 可能是数据损坏" << std::endl;
                return false;
            }
            
            // 重要修正：如果解析出的长度明显小于实际接收的数据长度，使用实际长度作为备选
            /*if (total_len < 12 || total_len > mesg.size()) {
                std::cout << "警告：解析出的长度可能不正确，尝试使用实际接收长度: " << mesg.size() << " bytes" << std::endl;
                total_len = mesg.size();
            }*/
            
            // 不再因为长度不匹配而直接返回false，而是尝试使用实际长度解析
            if (mesg.size() < total_len)
            {
                std::cout << "警告：当前字符串长度(" << mesg.size() << " bytes)小于报文长度(" << total_len << " bytes)，使用实际长度" << std::endl;
                total_len = mesg.size();
            }
            
            // 此时说明长度够了可以开始处理
            std::cout << "开始解析报文，长度符合要求" << std::endl;

            // 定位到消息类型字段
            uint32_t mtype;
            memcpy(&mtype, mesg.data() + sizeof(total_len), sizeof(mtype));
            mtype = ntohl(mtype); // 转换为主机字节序
            std::cout << "解析出的消息类型: " << mtype << " (" << static_cast<int>(zj::MType::ADD_REQUEST) << ":ADD_REQUEST, " 
                      << static_cast<int>(zj::MType::ADD_RESPONSE) << ":ADD_RESPONSE)" << std::endl;

            // 定位到ID长度字段
            uint32_t idlen;
            memcpy(&idlen, mesg.data() + sizeof(total_len) + mtypeFieldsLength, sizeof(idlen));
            idlen = ntohl(idlen); // 转换为主机字节序
            std::cout << "解析出的ID长度: " << idlen << " bytes" << std::endl;
            
            // 安全检查：防止ID长度过大
            if (idlen > total_len - sizeof(total_len) - mtypeFieldsLength - sizeof(idlen)) {
                std::cout << "错误：ID长度过大(" << idlen << "), 可能是数据损坏" << std::endl;
                return false;
            }
            
            // 提取ID
            std::string id;
            if (idlen > 0) {
                id = std::string(mesg, sizeof(total_len) + mtypeFieldsLength + sizeof(idlen), idlen);
            }
            std::cout << "解析出的ID: " << (id.empty() ? "(空)" : id) << std::endl;

            // 计算body部分的偏移量和大小
            size_t body_offset = sizeof(total_len) + mtypeFieldsLength + sizeof(idlen) + idlen;
            size_t body_size = mesg.size() - body_offset;
            std::cout << "body偏移量: " << body_offset << ", body大小: " << body_size << " bytes" << std::endl;
            
            // 安全检查
            if (body_offset + body_size > mesg.size()) {
                std::cout << "错误：body数据越界，可能是数据损坏" << std::endl;
                return false;
            }

            // 提取body，body从ID之后开始
            std::string body1;
            if (body_size > 0) {
                body1 = std::string(mesg, body_offset, body_size);
                
                // 打印body的前10个字节（如果有的话）
                std::cout << "body前10字节(十六进制): ";
                for (size_t i = 0; i < std::min<size_t>(10, body1.size()); ++i) {
                    std::cout << std::hex << std::setw(2) << std::setfill('0') 
                              << static_cast<int>(static_cast<unsigned char>(body1[i])) << " ";
                }
                std::cout << std::dec << std::endl;
                
                // 打印完整的body内容（不包含二进制字符），用于调试JSON解析问题
                std::cout << "完整的body内容: ";
                for (char c : body1) {
                    if (std::isprint(static_cast<unsigned char>(c)) || c == '\n' || c == '\t') {
                        std::cout << c;
                    } else {
                        std::cout << "[0x" << std::hex << std::setw(2) << std::setfill('0') 
                                  << static_cast<int>(static_cast<unsigned char>(c)) << std::dec << "]";
                    }
                }
                std::cout << std::endl;
            }
            
            std::cout << "准备反序列化body，长度: " << body1.size() << " bytes" << std::endl;
            
            // 填充BaseMessage对象body
            bool unserialize_result = body->unserialize(body1);
            if (!unserialize_result) {
                std::cout << "错误：body反序列化失败" << std::endl;
                return false;
            }
            
            body->setId(id);
            body->setMType((MType)mtype);
            
            // 截断mesg，移除已处理的部分
            std::cout << "准备截断mesg，当前大小: " << mesg.size() << ", 截断长度: " << mesg.size() << std::endl;
            mesg.erase(0, mesg.size());
            std::cout << "截断后mesg大小: " << mesg.size() << " bytes" << std::endl;
            
            std::cout << "到这了,通过Decode" << std::endl;
            return true; // 解析成功
        }
    };
}
